package org.apache.james.hibernate.entity;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Transient;

@Entity
public class Mail {

	Integer id;
	
	long uid;
	
	Date internalDate;
	
	String key;
	
	int size;
	
	MailBody mailBody;
	
	NamespaceImpl namespace;

	String envelope;
	
	String bodyStructure;
	
	
	Set<MailHeader> headers = new HashSet<MailHeader> ();
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	
	public long getUid() {
		return uid;
	}
	
	public void setUid(long uid) {
		this.uid = uid;
	}

	public Date getInternalDate() {
		return internalDate;
	}
	
	public void setInternalDate(Date internalDate) {
		this.internalDate = internalDate;
	}
	
	@Column(name="mail_key", nullable = false, length = 20)
	public String getKey() {
		return key;
	}
	
	public void setKey(String key) {
		this.key = key;
	}
	
	public int getSize() {
		return size;
	}
	
	public void setSize(int size) {
		this.size = size;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (obj == this) {
			return true;
		}
		if (obj instanceof Mail) {
			return ((Mail)obj).getId().equals(getId());
		}
		return false;
	}
	
	@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	@PrimaryKeyJoinColumn
	public MailBody getMailBody() {
		return mailBody;
	}
	
	public void setMailBody(MailBody mailBody) {
		this.mailBody = mailBody;
	}

	@ManyToOne(optional = false, fetch= FetchType.LAZY, cascade = {})
	public NamespaceImpl getNamespace() {
		return namespace;
	}
	
	public void setNamespace(NamespaceImpl namespace) {
		this.namespace = namespace;
	}

	@OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.REMOVE})
	@JoinColumn(name="mailId")
	public Set<MailHeader> getHeaders() {
		return headers;
	}
	
	public void setHeaders(Set<MailHeader> headers) {
		this.headers = headers;
	}
	
	@Column(nullable=true)
	public String getBodyStructure() {
		return bodyStructure;
	}
	public void setBodyStructure(String bodyStructure) {
		this.bodyStructure = bodyStructure;
	}

	@Column(nullable=true)
	public String getEnvelope() {
		return envelope;
	}
	
	public void setEnvelope(String envelope) {
		this.envelope = envelope;
	}

	@Transient
	public void addHeader(MailHeader mh) {
//		mh.setMailId(this.getId());
		headers.add(mh);
	}
	
	@Transient
	// TODO : figure out why it's doesn't works automaticly with hibernate?
	// @PostPersist
	public void onPersist() {
		for (MailHeader header: headers) {
			header.setMailId(getId());
		}
	}
	
}
